package cs342.uwosh.group1.mycontacts;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mycontacts.R;
import com.mycontacts.R.id;
import com.mycontacts.R.layout;
import com.mycontacts.R.menu;

import cs342.uwosh.group1.mycontacts.Threads.AddContactTask;
import cs342.uwosh.group1.mycontacts.Threads.DeleteContactTask;
import cs342.uwosh.group1.mycontacts.Threads.GetAllCategoryNamesTask;
import cs342.uwosh.group1.mycontacts.Threads.GetAllContactTask;
import cs342.uwosh.group1.mycontacts.Threads.GetContactsByCategoryTask;
import cs342.uwosh.group1.mycontacts.Threads.UpdateUserData;


import android.R.color;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.Layout;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

	public static ListView listOfContacts;
	public int categoryToEdit;
	public static ArrayAdapter<Contact> contactListAdapter;

	public static HashMap<String,Contact> allContacts = new HashMap<String,Contact>();

	public static String EXTRA_MESSAGE;
	public static SqlConnect db;

	public static Context mainContext;
	public EditText contactSearch;
	public Contact longClickedContact;

	public static int categoryViewed = 0;
	public static boolean loggedIn = false;
	public static boolean changed = false;
	
	public static int THEME_SET;
	public static TextView allContactsView;
	public static TextView catOneView;
	public static TextView catTwoView;
	public static TextView catThreeView;
	public static TextView catFourView;
	public static TextView catFiveView;
	public static TextView changeTheme;
	public static TextView contactItem;
	public static String[] themes = {"Theme 1","Theme 2","Theme 3"};
	
	SharedPreferences mPrefs;
	public static boolean signedIn = false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Themes.onActivityCreateSetTheme(this);
		setContentView(R.layout.activity_main);
		
		mainContext = this;
		
		Context mContext = this.getApplicationContext();
	    mPrefs = mContext.getSharedPreferences("myPrefs", MODE_PRIVATE);
	   
	    THEME_SET = mPrefs.getInt("THEME_SET", 1);
	    
	    if(mPrefs.getBoolean("firstRun", true)){
	    	SharedPreferences.Editor edit = mPrefs.edit();
		    edit.putBoolean("firstRun", false);
		    edit.commit();
	        logging();
	    }else{
	    	signedIn = true;
	    }
	    ////////////////
	    //SharedPreferences.Editor edit = mPrefs.edit();
	    //edit.putBoolean("firstRun", true);
	    //edit.commit();
	    //////////////////////////
	    System.out.println("Username = " + mPrefs.getString("username", ""));
	    System.out.println("Password = " + mPrefs.getString("password", ""));
		
		//Check if device is connected to the internet
		/*NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
	    if (networkInfo != null && networkInfo.isConnected()) {
	        //device is connected, grab required data
	    	//new CreateUserOnCloud().execute("someUsername","somePassword","jsonDataToBeStored");
	    } else {
	        //throw error about connection
	    }*/

		db = new SqlConnect(this);
		
		int useId = mPrefs.getInt("uid", 0);
		String useTheId = Integer.toString(useId);
		String x = db.downloadUserData(useTheId,"10");
		System.out.println("JSON STRING! :D");
		System.out.println(x);
		if(!x.equals("Up to Date")){
			db.updateDatabaseWithJson(x);
			int vers = db.grabVersion(useTheId);
			System.out.println(vers);
		}
		populateView();
		
	}
	
	public void populateView(){
		allContactsView = (TextView) findViewById(R.id.allCons);
		catOneView = (TextView) findViewById(R.id.catOne);
		catTwoView = (TextView) findViewById(R.id.catTwo);
		catThreeView = (TextView) findViewById(R.id.catThree);
		catFourView = (TextView) findViewById(R.id.catFour);
		catFiveView = (TextView) findViewById(R.id.catFive);
		changeTheme = (TextView) findViewById(R.id.themeSelect);
		listOfContacts = (ListView) findViewById(R.id.contactsListView);
		contactItem = (TextView) findViewById(R.id.contactItem);
		contactSearch = (EditText) findViewById(R.id.contactSearch);
		
		new GetAllContactTask().execute();
		listOfContacts.setOnItemClickListener(new OnItemClickListener()
		{

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long arg3)
			{
				Contact clickedContact = contactListAdapter.getItem(position);
				viewContact(clickedContact);
			}	
		});
		registerForContextMenu(listOfContacts);
		registerForContextMenu(catOneView);
		registerForContextMenu(catTwoView);
		registerForContextMenu(catThreeView);
		registerForContextMenu(catFourView);
		registerForContextMenu(catFiveView);
		registerForContextMenu(changeTheme);
		
		changeTheme.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				clickChangeTheme();
			}
		});

		allContactsView.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				clickAllCons();
			}
		});

		catOneView.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				clickOne();
			}
		});

		catTwoView.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				clickTwo();
			}
		});

		catThreeView.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				clickThree();
			}
		});

		catFourView.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				clickFour();
			}
		});

		catFiveView.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				clickFive();
			}
		});

		new GetAllCategoryNamesTask().execute();
		
		contactSearch.addTextChangedListener(new TextWatcher(){

			@Override
			public void afterTextChanged(Editable arg0) {
				
			}

			@Override
			public void beforeTextChanged(CharSequence arg0, int arg1,
					int arg2, int arg3) {
				
			}

			@Override
			public void onTextChanged(CharSequence arg0, int arg1, int arg2,
					int arg3) {
				contactListAdapter.getFilter().filter(arg0);
			}
			
		});
		changeCategoyButtonBackground(allContactsView);
	}
	
	protected void onDestroy(){
	    super.onDestroy();
		try
	    {
	    	if(changed){
	    		String data = db.getDatabaseAsJson();
	    		String id = Integer.toString(mPrefs.getInt("uid", 0));
	    		int curVer = mPrefs.getInt("ver", 0);
	    		curVer++;
	    		SharedPreferences.Editor edit = mPrefs.edit();
			    edit.putInt("ver", curVer);
			    edit.commit();
				String version = Integer.toString(curVer);
			    System.out.println(data);
			    System.out.println(id);
			    new UpdateUserData().execute(id,data,version);
	    	}
	    }
	    catch (Exception e)
	    {
	     // this is the line of code that sends a real error message to the log
	     Log.e("ERROR", "ERROR IN CODE: " + e.toString());
	    
	     // this is the line that prints out the location in
	     // the code where the error occurred.
	     e.printStackTrace();
	    }
	}
	
	public void logging(){
		Intent intent = new Intent(this, LoginActivity.class);
		startActivity(intent);
	}

	/**
	 * Things to happen on resume:
	 * display the correct names for all categories
	 * display the correct list for which category should be shown
	 * should probably highlight the category being viewed in a diff color
	 */
	public void onResume()
	{
		super.onResume();
		//new GetAllCategoryNamesTask().execute(); // displaying the proper names for each category
		/*if(!signedIn){
			logging();
		}*/
		if(loggedIn){
			int useId = mPrefs.getInt("uid", 0);
			String useTheId = Integer.toString(useId);
			String x = db.downloadUserData(useTheId,"-1");
			System.out.println("JSON STRING! :D");
			System.out.println(x);
			if(!x.equals("Up to Date")){
				db.updateDatabaseWithJson(x);
			}
			int vers = db.grabVersion(useTheId);
			SharedPreferences.Editor edit = mPrefs.edit();
		    edit.putInt("ver", vers);
		    edit.commit();
			System.out.println(vers);
			populateView();
			loggedIn = false;
		}
		if (categoryViewed != 0){
			switch(categoryViewed)
			{
			case 1:
				changeCategoyButtonBackground(catOneView);
				clickOne();
				break;
			case 2:
				changeCategoyButtonBackground(catTwoView);
				clickTwo();
				break;
				
			case 3:
				changeCategoyButtonBackground(catThreeView);
				clickThree();
				break;
				
			case 4:
				changeCategoyButtonBackground(catFourView);
				clickFour();
				break;
				
			case 5:
				changeCategoyButtonBackground(catFiveView);
				clickFive();
				break;
			}
			new GetContactsByCategoryTask().execute(categoryViewed);
		}
		
	}
	

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		MenuInflater inflater = getMenuInflater();
		if (v == listOfContacts)
		{
			inflater.inflate(R.menu.contacts_list_context_menu, menu);
			AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
			longClickedContact = contactListAdapter.getItem(info.position);
		}
		else if (v == catOneView)
		{
			this.categoryToEdit = 1;
			inflater.inflate(R.menu.long_click_category_context_menu, menu);
		}
		else if (v == catTwoView)
		{
			this.categoryToEdit = 2;
			inflater.inflate(R.menu.long_click_category_context_menu, menu);			
		}
		else if (v == catThreeView)
		{
			this.categoryToEdit = 3;
			inflater.inflate(R.menu.long_click_category_context_menu, menu);		
		}
		else if (v == catFourView)
		{
			this.categoryToEdit = 4;
			inflater.inflate(R.menu.long_click_category_context_menu, menu);		
		}
		else if (v == catFiveView)
		{
			this.categoryToEdit = 5;
			inflater.inflate(R.menu.long_click_category_context_menu, menu);		
		}
		else
		{
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item)
	{
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		switch (item.getItemId()) {
		case R.id.delete_contact:
			deleteContact(longClickedContact);
			return true;
		case R.id.edit_category:
			Intent intent = new Intent(this, CreateEditCategoryActivity.class);
			intent.putExtra(EXTRA_MESSAGE, ""+this.categoryToEdit);
			startActivity(intent);
			return true;
		default:
			return super.onContextItemSelected(item);
		}
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		switch (item.getItemId()) {
		case R.id.delete_contact:
			Intent intent1 = new Intent(this, DeleteContactsChooser.class);
			startActivity(intent1);
			return true;
		case R.id.create_category:
			final int totalCategories = db.categoryCount();
			if(totalCategories < 5)
			{
				switch(totalCategories + 1)
				{
					case 1:
						clickOne();
						return true;
					case 2:
						clickTwo();
						return true;
					case 3:
						clickThree();
						return true;
					case 4:
						clickFour();
						return true;
					case 5:
						clickFive();
						return true;
					}
					return true;
			}
			else
			{
				showCategorySelector();
			}
			return true;
		case R.id.edit_category_menu:
			showCategorySelector();
			return true;
		case R.id.add_contact:
			Intent intent2 = new Intent(this, AddContact.class);
			startActivity(intent2);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
		
	}
	
	private void showCategorySelector()
	{
		final CharSequence[] categoriesList = {catOneView.getText(),catTwoView.getText(), 
				catThreeView.getText(), catFourView.getText(), catFiveView.getText()};
		AlertDialog.Builder alert = new AlertDialog.Builder(this);

		alert.setTitle("Select Category");

		alert.setSingleChoiceItems(categoriesList,-1, new 

		DialogInterface.OnClickListener()

		{

		    @Override
		    public void onClick(DialogInterface dialog, int which) 
		    {
		    	if(categoriesList[which] == catOneView.getText())
		    	{
		    		editCategoryMenu(1);
		    		dialog.cancel();
		    	}
		    	else if(categoriesList[which] == catTwoView.getText())
		    	{
		    		editCategoryMenu(2);
		    		dialog.cancel();
		    	}
		    	else if(categoriesList[which] == catThreeView.getText())
		    	{
		    		editCategoryMenu(3);
		    		dialog.cancel();
		    	}
		    	else if(categoriesList[which] == catFourView.getText())
		    	{
		    		editCategoryMenu(4);
		    		dialog.cancel();
		    	}
		    	else if(categoriesList[which] == catFiveView.getText())
		    	{
		    		editCategoryMenu(5);
		    		dialog.cancel();
		    	}
		    }

		});
		alert.show();
	}
	
	private void editCategoryMenu(int catID)
	{
		Intent intent = new Intent(this, CreateEditCategoryActivity.class);
		intent.putExtra(EXTRA_MESSAGE, ""+catID);
		startActivity(intent);
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main_menu, menu);
		
		return true;
	}

	/**
	 * Passes in a contact and then passes their ID to the DisplayContact
	 * activity.
	 * @param contact The contact who's ID is being passed to DisplayContact
	 */
	public void viewContact(Contact contact)
	{
		Intent intent = new Intent(this, AddContact.class);
		intent.putExtra(EXTRA_MESSAGE, ""+contact.getId());
		startActivity(intent);
	}
	/**
	 * Opens the add contact activity
	 * @param view
	 */
	//AddTest
	public void add(View view){
		Intent intent = new Intent(this, AddContact.class);
		startActivity(intent);
	}
	/**
	 * Called to delete a contact
	 * @param contactToDelete The contact to be deleted.
	 */
	public void deleteContact(Contact contactToDelete)
	{
		new DeleteContactTask().execute(contactToDelete);
	}

	
	public void changeCategoyButtonBackground(TextView clickedView)
	{
		
		if(THEME_SET == 1){
			catOneView.setBackgroundResource(R.layout.red_btn_t1);
	    	catTwoView.setBackgroundResource(R.layout.red_btn_t1);
			catThreeView.setBackgroundResource(R.layout.red_btn_t1);
			catFourView.setBackgroundResource(R.layout.red_btn_t1);
			catFiveView.setBackgroundResource(R.layout.red_btn_t1);
			allContactsView.setBackgroundResource(R.layout.red_btn_t1);
			clickedView.setBackgroundResource(R.layout.red_button_been_pressed_t1);
			
		}
		if(THEME_SET == 2){
			catOneView.setBackgroundResource(R.layout.button_t2);
	    	catTwoView.setBackgroundResource(R.layout.button_t2);
			catThreeView.setBackgroundResource(R.layout.button_t2);
			catFourView.setBackgroundResource(R.layout.button_t2);
			catFiveView.setBackgroundResource(R.layout.button_t2);
			allContactsView.setBackgroundResource(R.layout.button_t2);
			clickedView.setBackgroundResource(R.layout.button_pressed_t2);
			
			//list item colors to #1e663d or rgb(30,102,61)
			setActivityBackgroundColor(Color.rgb(16,51,31));
		}
		if(THEME_SET == 3){
			catOneView.setBackgroundResource(R.layout.button_t3);
	    	catTwoView.setBackgroundResource(R.layout.button_t3);
			catThreeView.setBackgroundResource(R.layout.button_t3);
			catFourView.setBackgroundResource(R.layout.button_t3);
			catFiveView.setBackgroundResource(R.layout.button_t3);
			allContactsView.setBackgroundResource(R.layout.button_t3);
			clickedView.setBackgroundResource(R.layout.button_pressed_t3);
			
			//change list item colors to #627d85 or rgb(98,125,133)
			//contactItem.setBackgroundColor(Color.rgb(98,125,133));
			//LinearLayout themeLayout = (LinearLayout) findViewById(R.id.themeLayout);
			//themeLayout.setBackgroundResource(R.id.color_list_items_t3);
			
			
			setActivityBackgroundColor(Color.rgb(42,84,97));		
		}
	}
	
	public void setActivityBackgroundColor(int color) {
	    View view = this.getWindow().getDecorView();
	    view.setBackgroundColor(color);
	}
	
	public void clickAllCons()
	{
		new GetAllContactTask().execute();
		categoryViewed = 0;
		changeCategoyButtonBackground(allContactsView);
	}
	public void clickChangeTheme()
	{
		DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener(){
			@Override
    	    public void onClick(DialogInterface dialog, int which)
    	    {
				SharedPreferences.Editor editTheme = mPrefs.edit();
				switch (which){
				case 0:
				    editTheme.putInt("THEME_SET", 1);
				    editTheme.commit();
					Themes.changeToTheme(MainActivity.this, Themes.THEME_1);
					break;
				case 1:
				    editTheme.putInt("THEME_SET", 2);
				    editTheme.commit();
					Themes.changeToTheme(MainActivity.this, Themes.THEME_2);
					break;
				case 2:
				    editTheme.putInt("THEME_SET", 3);
				    editTheme.commit();
					Themes.changeToTheme(MainActivity.this, Themes.THEME_3);
					break;
				}
    	    }
		};
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	builder.setTitle("Change Theme");
    	builder.setItems(themes, dialogClickListener).show();
	}

	public void clickOne()
	{
        final int totalCategories = db.categoryCount();
        if(totalCategories < 1)
        {
        	DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
        	{
        	    @Override
        	    public void onClick(DialogInterface dialog, int which)
        	    {
        	        switch (which)
        	        {
        	        case DialogInterface.BUTTON_POSITIVE:
        	        	launchCreateEditCategory(totalCategories);
        	            break;
        	        case DialogInterface.BUTTON_NEGATIVE:
        	            break;
        	        }
        	    }
        	};
        	AlertDialog.Builder builder = new AlertDialog.Builder(this);
        	builder.setMessage("Create Category?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
        }
        else
        {
        	new GetContactsByCategoryTask().execute(1);
        	changeCategoyButtonBackground(catOneView);
        	categoryViewed = 1;
        }
	}
	
	public void launchCreateEditCategory(int totalCategories)
	{
		totalCategories++;
		Intent intent = new Intent(this, CreateEditCategoryActivity.class);
		intent.putExtra(EXTRA_MESSAGE, ""+totalCategories);
		startActivity(intent);
	}
	
	public void clickTwo()
	{
		final int totalCategories = db.categoryCount();
        if(totalCategories < 2)
        {
        	DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
        	{
        	    @Override
        	    public void onClick(DialogInterface dialog, int which)
        	    {
        	        switch (which)
        	        {
        	        case DialogInterface.BUTTON_POSITIVE:
        	        	launchCreateEditCategory(totalCategories);
        	            break;
        	        case DialogInterface.BUTTON_NEGATIVE:
        	            break;
        	        }
        	    }
        	};
        	AlertDialog.Builder builder = new AlertDialog.Builder(this);
        	builder.setMessage("Create Category?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
        }
        else
        {
        	new GetContactsByCategoryTask().execute(2);
        	changeCategoyButtonBackground(catTwoView);
        	categoryViewed = 2;
        }
	}
	
	public void clickThree()
	{
		final int totalCategories = db.categoryCount();
        if(totalCategories < 3)
        {
        	DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
        	{
        	    @Override
        	    public void onClick(DialogInterface dialog, int which)
        	    {
        	        switch (which)
        	        {
        	        case DialogInterface.BUTTON_POSITIVE:
        	        	launchCreateEditCategory(totalCategories);
        	            break;
        	        case DialogInterface.BUTTON_NEGATIVE:
        	            break;
        	        }
        	    }
        	};
        	AlertDialog.Builder builder = new AlertDialog.Builder(this);
        	builder.setMessage("Create Category?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
        }
        else
        {
        	new GetContactsByCategoryTask().execute(3);
        	changeCategoyButtonBackground(catThreeView);
        	categoryViewed = 3;
        }
	}
	
	public void clickFour()
	{
		final int totalCategories = db.categoryCount();
        if(totalCategories < 4)
        {
        	DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
        	{
        	    @Override
        	    public void onClick(DialogInterface dialog, int which)
        	    {
        	        switch (which)
        	        {
        	        case DialogInterface.BUTTON_POSITIVE:
        	        	launchCreateEditCategory(totalCategories);
        	            break;
        	        case DialogInterface.BUTTON_NEGATIVE:
        	            break;
        	        }
        	    }
        	};
        	AlertDialog.Builder builder = new AlertDialog.Builder(this);
        	builder.setMessage("Create Category?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
        }
        else
        {
        	new GetContactsByCategoryTask().execute(4);
        	changeCategoyButtonBackground(catFourView);
        	categoryViewed = 4;
        }
	}
	
	public void clickFive()
	{
		final int totalCategories = db.categoryCount();
        if(totalCategories < 5)
        {
        	DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
        	{
        	    @Override
        	    public void onClick(DialogInterface dialog, int which)
        	    {
        	        switch (which)
        	        {
        	        case DialogInterface.BUTTON_POSITIVE:
        	        	launchCreateEditCategory(totalCategories);
        	            break;
        	        case DialogInterface.BUTTON_NEGATIVE:
        	            break;
        	        }
        	    }
        	};
        	AlertDialog.Builder builder = new AlertDialog.Builder(this);
        	builder.setMessage("Create Category?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", dialogClickListener).show();
        }
        else
        {
        	new GetContactsByCategoryTask().execute(5);
        	changeCategoyButtonBackground(catFiveView);
        	categoryViewed = 5;
        }
	}

}
